#include <iostream>
#include <string.h>

using namespace std;

class Computer{
public:
    //构造函数(深拷贝)
    Computer(const char *brand,int price)
    :_brand(new char[strlen(brand)+1]())
    ,_price(price)
    {
        strcpy(_brand,brand);
    }

    //析构函数
    ~Computer(){
        if(_brand!=nullptr){
            delete[] _brand;
            _brand=nullptr;
        }
    }

    //拷贝构造函数
    //1.const不能去掉：去掉意味着可以任意修改有操作数的值,
    //                 并且没法绑定临时对象的拷贝
    //2.&不能去掉：如果去掉&，参数就会变成按值传递，这会立即触发拷贝构造,
    //             导致无限递归调用
    Computer(const Computer &rhs)
    :_brand(new char[strlen(rhs._brand)+1]())
    ,_price(rhs._price)
    {
        strcpy(_brand,rhs._brand);
    }

    //赋值运算符函数
    Computer &operator=(const Computer &rhs){
        //这里的&是取地址的意思
        if(this!=&rhs){
            delete[] _brand;
            _brand=new char[strlen(rhs._brand)+1]();
            strcpy(_brand,rhs._brand);
            _price=rhs._price;
        }
        return *this;
    }

    //移动构造函数
    Computer(Computer &&rhs)
    :_brand(rhs._brand)
    ,_price(rhs._price)
    {
        rhs._brand=nullptr;
        cout << "Computer(Computer &&)" << endl;
    }

    //移动赋值函数
    Computer &operator=(Computer &&rhs){
        if(this!=&rhs){
            delete[] _brand;
            _brand=rhs._brand; //浅拷贝
            rhs._brand=nullptr;
            _price=rhs._price;
        }
        cout << "Computer &operator=(Computer &&)" << endl;
        return *this;
    }

    void print(){
        cout << "brand:" << _brand << ",price:" << _price << endl;
    }

private:
    char *_brand;
    int _price;
};

class MyComputer
:public Computer
{
public:
    //继承中的构造函数
    MyComputer(const char *brand,int price,const char *name,int age)
    :Computer(brand,price) //显示调用基类的构造函数
    ,_name(new char[strlen(name)+1]())
    ,_age(age)
    {
        strcpy(_name,name);
    }

    //析构函数
    ~MyComputer(){
        if(_name!=nullptr){
            delete[] _name;
            _name=nullptr;
        }
    }

    //继承中的拷贝构造函数
    MyComputer(const MyComputer &rhs)
    :Computer(rhs) //显示调用基类的拷贝构造函数，基类引用绑定派生类对象
    ,_name(new char[strlen(rhs._name)+1]())
    ,_age(rhs._age)
    {
        strcpy(_name,rhs._name);
    }

    //继承中的赋值运算符函数
    MyComputer &operator=(const MyComputer &rhs){
        if(this!=&rhs){
            Computer::operator=(rhs); //显示调用基类的赋值运算符函数
            delete[] _name;
            _name=new char[strlen(rhs._name)+1]();
            strcpy(_name,rhs._name);
            _age=rhs._age;
        }
        return *this;
    }

    void print(){
        Computer::print();
        cout << "姓名:" << _name << ",年龄:" << _age << endl;
    }


private:
    char *_name;
    int _age;
};

void test(){
    Computer c1("Apple",12000);
    Computer c2("Huawei",10000);
    //拷贝
    Computer c3=c1;
    //赋值
    c2=c1;
    //移动构造
    //如果不加move，编译器会自动优化，从而不会调用移动构造函数
    Computer c4=move(Computer("Xiaomi",5000));
    //移动赋值
    //如果不加move，编译器会自动优化，从而不会调用移动赋值函数
    c1=move(Computer("Samsung",10000));
    c1.print();
    c2.print();
    c3.print();
    c4.print();

    MyComputer mc1("Apple",12000,"Alice",22);
    MyComputer mc2=mc1;
    MyComputer mc3("Huawei",10000,"Tom",20);
    mc1.print();
    mc2.print();
    mc1=mc3;
    mc1.print();
}

int main()
{
    test();
    return 0;
}

